package com.game.number;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

public class Box2D {
	
	private List<Unit> units=new ArrayList<Unit>();
	
	private HashMap<String,Unit> map=new HashMap<String,Unit>();
	
	private String activePos;
	
	private Box2D parentBox2D = null;
	
	public Box2D getParentBox2D() {
		return parentBox2D;
	}

	public void setParentBox2D(Box2D parentBox2D) {
		this.parentBox2D = parentBox2D;
	}

	public Box2D(List<Unit> constructUnits){
		this.units.addAll(constructUnits);
		if(!validBox())
			throw new RuntimeException("Invalid Box.");
		
		for(Unit unit:this.units){
			map.put(unit.getPosition(), unit);
		}
		
	}
	
	public void switchPosition(Unit unitA,Unit unitB){
		String position=unitA.getPosition();
		unitA.setPosition(unitB.getPosition());
		unitB.setPosition(position);
		
		map.put(unitA.getPosition(), unitA);
		map.put(unitB.getPosition(), unitB);
	}
	
	public Unit getUpUnit(Unit unitA){
		if(upable(unitA)){
			String position=this.getUnitX(unitA)+","+(this.getUnitY(unitA)-1);
			return findUnitByPosition(position);
		}
		return null;
	}
	
	public Unit getDownUnit(Unit unitA){
		if(downable(unitA)){
			String position=this.getUnitX(unitA)+","+(this.getUnitY(unitA)+1);
			return findUnitByPosition(position);
		}
		return null;
	}
	
	public Unit getLeftUnit(Unit unitA){
		if(leftable(unitA)){
			String position=(this.getUnitX(unitA)-1)+","+this.getUnitY(unitA);
			return findUnitByPosition(position);
		}
		return null;
	}
	
	public Unit getRightUnit(Unit unitA){
		if(rightable(unitA)){
			String position=(this.getUnitX(unitA)+1)+","+this.getUnitY(unitA);
			return findUnitByPosition(position);
		}
		return null;
	}

	public boolean upable(Unit unit){
		if(this.getUnitY(unit)==1)
			return false;
		else 
			return true;
	}
	
	public boolean leftable(Unit unit){
		if(this.getUnitX(unit)==1)
			return false;
		else
			return true;
	}
	
	public boolean rightable(Unit unit){
		if(this.getUnitX(unit)==3)
			return false;
		else 
			return true;
	}
	
	public boolean downable(Unit unit){
		if(this.getUnitY(unit)==3)
			return false;
		else
			return true;
	}
	
	public List<Unit> getUnits(){
		return this.units;
	}
	
	public void addUnit(Unit unit){
		this.units.add(unit);	
	}
	
	protected boolean validBox(){
		
		return true;
	}
	
	private int getUnitX(Unit unit){
		String[] xy=unit.getSplitPosition();
		return Integer.parseInt(xy[0]);
	}
	
	private int getUnitY(Unit unit){
		String[] xy=unit.getSplitPosition();
		return Integer.parseInt(xy[1]);
	}
	
	public Unit findUnitByPosition(String position){
		return map.get(position);
	}
	
	@Override
	public boolean equals(Object obj){
		if(!(obj instanceof Box2D)){
			return false;
		}else{
			Box2D box2=(Box2D)obj;
			for(Unit unit:this.units){
				if(!box2.findUnitByPosition(unit.getPosition()).getValue().equals(unit.getValue())){
					return false;
				}
			}
			
			return true;
		}
	}
	
	public Box2D clone(){
		List<Unit> cloneUnits=new ArrayList<Unit>();
		for(Unit unit:this.units){
			cloneUnits.add(unit.Clone());
		}
		Box2D newBox2D=new Box2D(cloneUnits);
		return newBox2D;
	}

	public String getActivePos() {
		return activePos;
	}

	public void setActivePos(String activePos) {
		this.activePos = activePos;
	}
	
	public String snapshot(){
		Collections.sort(this.units, new UnitComparator());
		
		StringBuffer sb=new StringBuffer();
		for(Unit unit:this.units){
			sb.append(unit.snapshot());
		}
		
		return sb.toString();
	}
	
	
	
	
}
